class Title < ActiveRecord::Base
  belongs_to  :character
  has_many    :relation
  
  def Title.name_of(category, sub_category, sex, domain=nil)
    subcat = Title.sub_categories(category.to_i)[sub_category.to_i]
    ret = subcat[sex]
    ret = subcat["male"] unless ret
    if domain && domain.respond_to?("name")
      ret += " of " + domain.name
    end
    return ret
  end
  
  def Title.title_choice (title)
    return [nil,nil] unless title
    title_array = title.split(":")
    if title_array
      title_array[0] = title_array[0].to_i
      title_array[0] = title_array[0].to_i
    end  
    return title_array
  end
  
  def Title.is_king?(category, sub_category)
    (category == 1 && sub_category == 6)
  end
  
  def Title.is_cardinal?(category, sub_category)
    (category == 2 && sub_category == 4)
  end
  
  def Title.is_duke?(category, sub_category)
    (category == 1 && sub_category == 5)
  end
  
  def Title.is_bishop?(category, sub_category)
    (category == 2 && sub_category == 3)
  end
  
  def Title.is_count?(category, sub_category)
    (category == 1 && sub_category == 4)
  end
  
  def Title.is_dean?(category, sub_category)
    (category == 2 && sub_category == 2)
  end
  
  def Title.is_earl?(category, sub_category)
    (category == 1 && sub_category == 3)
  end
  
  def Title.is_valid_territory?(category, sub_category, territory)
    if Title.is_king?(category, sub_category) || Title.is_cardinal?(category, sub_category)
      return territory.instance_of? Kingdom  
    end
    if Title.is_duke?(category, sub_category) || Title.is_bishop?(category, sub_category)
      return territory.instance_of? Duchy  
    end
    if Title.is_count?(category, sub_category)
      return territory.instance_of? County  
    end
    if Title.is_earl?(category, sub_category) || Title.is_dean?(category, sub_category)
      return territory.instance_of? Town  
    end
    return true
  end
  
  def Title.revoke_title(character, category, sub_category, territory = nil)
    return nil unless character && category && sub_category
    title = nil
    if territory
      title = Title.find_by_character_id_and_category_and_sub_category_and_territory(character.id, category, sub_category, territory.id)
    end
    title = Title.find_by_character_id_and_category_and_sub_category(character.id, category, sub_category) unless title
    title.revoke
  end
  
  def Title.grant_title (character, category, sub_category, territory = nil)
    return nil unless character && category && sub_category
    title_name = Title.name_of(category, sub_category, character.sex, territory)
    # sanity checks on territory
    raise "Invalid territory for #{title_name}" unless Title.is_valid_territory?(category.to_i, sub_category.to_i, territory)
    
    if territory
      # destroy existing feudal / ecclesiastical title for this territory
      title = Title.find_by_category_and_sub_category_and_territory(category, sub_category, territory.id)
      id = title.id unless title.nil?
      old_title_holder = title.character unless title.nil?
      title.destroy unless title.nil?
      # if old title holder has no titles after this transfer of title, give them a lord title
      if old_title_holder && (old_title_holder.titles.nil? or old_title_holder.titles.size < 1)
        Title.grant_title(old_title_holder, 1, 1)
      end
      # previous vassals of this title become vassals of new title holder
      if id
        vassals = Relation.find_all_by_title_id_and_category (id, 1)
        if vassals
          vassals.each do |rel|
            Title.revoke_court_titles rel.character # remove any court titles before changing allegiance
            rel.title_id = character.highest_title.id
            rel.save
          end
        end
      end
      liege = character.liege
      if liege
        # break vassalage if given a title equal to the liege's highest title
        highest_title = liege.highest_title
        if highest_title && highest_title.sub_category <= sub_category
          Relation.cancel_vassalage character
        end
      end
    end
    
    if category == 3
      # destroy existing title for court titles for the same liege
      titles = Title.find_by_court (sub_category, character.court_territory)
      if titles
        titles.each do |title|
          old_title_holder = title.character
          title.destroy
          # if old title holder has no titles after this transfer of title, give them a lord title
          if old_title_holder
            if (old_title_holder.titles.nil? or old_title_holder.titles.size < 1)
              Title.grant_title(old_title_holder, 1, 1)
            end
            # if old title holder doesn't hold court, release his vassals
            Relation.free_vassals(old_title_holder) unless old_title_holder.ruler?
          end
        end
      end
    end
    
    title = Title.new
    title.category = category
    title.sub_category = sub_category
    title.territory = territory.id unless territory.nil?
    title.character_id = character.id
    return nil unless title.save
    
    # remove lord / priest title for character given a new non-court title
    if title.category != 3 && !(title.priest? or title.lord?)
      lord = Title.find_by_character_id_and_category_and_sub_category(character.id, 1, 1)
      lord.destroy unless lord.nil?
      priest = Title.find_by_character_id_and_category_and_sub_category(character.id, 2, 1)
      priest.destroy unless priest.nil?
    end
  
    # remove ecclesiastical titles if given a feudal title
    if title.category == 1
      Title.revoke_ecclesiastical_titles(character)
    end
    
    # transfer feudal titles to the character's successor if given an ecclesiastical title
    if title.category == 2
      successors = character.successors
      successor = nil
      successor = successors[0] unless successors.nil? or successors.size < 1
      Title.transfer_feudal_titles(character, successor)
    end
    
    return title
  end
  
  def Title.revoke_ecclesiastical_titles(character)
    titles = Title.find_all_by_category_and_character_id(2, character.id)
    if titles
      for title in titles
        title.destroy
      end
    end
  end
  
  def Title.revoke_court_titles(character)
    titles = Title.find_all_by_category_and_character_id(3, character.id)
    if titles
      for title in titles
        title.destroy
      end
    end
  end
  
  def Title.transfer_feudal_titles(from, to)
    titles = Title.find_all_by_category_and_character_id(1, from.id)
    if titles
      for title in titles
        if to && !(title.sub_category == 7 or title.sub_category == 1) # emperor and lord titles do not get transfered
          Title.grant_title(to, title.category, title.sub_category, title.domain)
        else
          title.destroy
        end
      end
    end
  end

  def Title.make_admiral (character)
    Title.grant_title character, 3, 1
  end
  
  def Title.make_constable (character)
    Title.grant_title character, 3, 2
  end
  
  def Title.make_marshal (character)
    Title.grant_title character, 3, 3
  end
  
  def Title.make_ambassador (character)
    Title.grant_title character, 3, 4
  end
  
  def Title.make_chamberlain (character)
    Title.grant_title character, 3, 5
  end
  
  def Title.make_comptroller (character)
    Title.grant_title character, 3, 6
  end
  
  def Title.make_steward (character)
    Title.grant_title character, 3, 7
  end
  
  def Title.make_chancellor (character)
    Title.grant_title character, 3, 8
  end
  
  def Title.make_priest (character)
    Title.grant_title character, 2, 1
  end
  
  def Title.make_dean (character, town)
    Title.grant_title character, 2, 2, town
  end
  
  def Title.make_bishop (character, duchy)
    Title.grant_title character, 2, 3, duchy
  end
  
  def Title.make_cardinal (character, kingdom)
    Title.grant_title character, 2, 4, kingdom
  end
  
  def Title.make_pope (character)
    Title.grant_title character, 2, 5
  end
  
  def Title.make_lord (character)
    Title.grant_title character, 1, 1
  end
  
  def Title.make_knight (character)
    Title.grant_title character, 1, 2
  end
  
  def Title.make_earl (character, town)
    Title.grant_title character, 1, 3, town
  end
  
  def Title.make_count (character, county)
    Title.grant_title character, 1, 4, county
  end
  
  def Title.make_duke (character, duchy)
    Title.grant_title character, 1, 5, duchy
  end
  
  def Title.make_king (character, kingdom)
    Title.grant_title character, 1, 6, kingdom
  end
  
  def Title.make_emperor (character)
    Title.grant_title character, 1, 7
  end
  
  def Title.king_of (kingdom)
    Title.title_holder 1, 6, kingdom
  end
  
  def Title.duke_of (duchy)
    Title.title_holder 1, 5, duchy
  end
  
  def Title.count_of (county)
    Title.title_holder 1, 4, county
  end
  
  def Title.earl_of (town)
    Title.title_holder 1, 3, town
  end
  
  def Title.emperor
    Title.title_holder 1, 7
  end
  
  def Title.pope
    Title.title_holder 2, 5
  end
  
  def Title.categories
    {
    1 => "Feudal",
    2 => "Ecclesiastical",
    3 => "Court"
    }
  end
  
  def Title.sub_categories (category)
    subcategories = {
    1 => {
      1 => {"male" => "Lord", "female" => "Lady"},
      2 => {"male" => "Knight","female" => "Dame", "prestige" => 10},
      3 => {"male" => "Earl","female" => "Countess", "prestige" => 25},
      4 => {"male" => "Count","female" => "Countess", "prestige" => 50},
      5 => {"male" => "Duke","female" => "Duchess", "prestige" => 100},
      6 => {"male" => "King","female" => "Queen", "prestige" => 250},
      7 => {"male" => "Holy Roman Emperor","female" => "Holy Roman Empress", "prestige" => 500}
    },
    2 => {
      1 => {"male" => "Priest", "female" => "Nun"},
      2 => {"male" => "Dean", "piety" => 25},
      3 => {"male" => "Bishop", "piety" => 50},
      4 => {"male" => "Cardinal", "piety" => 100},
      5 => {"male" => "Pope", "piety" => 250}
    },
    3 => {
      1 => {"male" => "Admiral", "prestige" => 50},
      2 => {"male" => "Constable", "prestige" => 25},
      3 => {"male" => "Marshal", "prestige" => 75},
      4 => {"male" => "Ambassador", "prestige" => 50},
      5 => {"male" => "Chamberlain", "prestige" => 25},
      6 => {"male" => "Comptroller of the Household", "prestige" => 50},
      7 => {"male" => "Steward", "prestige" => 50},
      8 => {"male" => "Chancellor", "prestige" => 100}
    }
    }
    return subcategories[category]
  end
  
  def Title.feudal
    Title.sub_categories 1
  end
  
  def Title.ecclesiastical
    Title.sub_categories 2
  end
  
  def Title.court
    Title.sub_categories 3
  end
  
  def Title.territory_type (category, subcategory)
    subcategories = {
    1 => {
      1 => nil,
      2 => nil,
      3 => "Town",
      4 => "County",
      5 => "Duchy",
      6 => "Kingdom",
      7 => nil
    },
    2 => {
      1 => nil,
      2 => "Town",
      3 => "Duchy",
      4 => "Kingdom",
      5 => nil
    },
    3 => {
      1 => nil,
      2 => nil,
      3 => nil,
      4 => nil,
      5 => nil,
      6 => nil,
      7 => nil,
      8 => nil
    }
    }
    return subcategories[category][subcategory]
  end
  
  def Title.salutations (category)
    subcategories = {
    1 => {
      1 => {"male" => "Lord", "female" => "Lady"},
      2 => {"male" => "Sir","female" => "Madam"},
      3 => {"male" => "Lord","female" => "Lady"},
      4 => {"male" => "Lord","female" => "Lady"},
      5 => {"male" => "Grace","female" => "Grace"},
      6 => {"male" => "Majesty","female" => "Majesty"},
      7 => {"male" => "Imperial Highness","female" => "Imperial Highness"}
    },
    2 => {
      1 => {"male" => "Father", "female" => "Sister"},
      2 => {"male" => "Dean"},
      3 => {"male" => "Bishop"},
      4 => {"male" => "Grace"},
      5 => {"male" => "Holiness"}
    },
    3 => {
      1 => {"male" => "Admiral"},
      2 => {"male" => "Constable"},
      3 => {"male" => "Marshal"},
      4 => {"male" => "Ambassador"},
      5 => {"male" => "Chamberlain"},
      6 => {"male" => "Comptroller of the Household"},
      7 => {"male" => "Steward"},
      8 => {"male" => "Chancellor"}
    }
    }
    return subcategories[category]
  end
  
  def Title.male_allowed? (category, subcategory)
    subcat = Title.sub_categories(category)[subcategory]
    return true unless subcat["male"].nil?
  end
  
   def Title.female_allowed? (category, subcategory)
    subcat = Title.sub_categories(category)[subcategory]
    return true unless subcat["female"].nil?
  end
  
  
  def grantable? (giver, receiver)
    # if title is feudal
    # - giver must have title already
    # - receiver cannot be clergy
    # OR giver must be king AND title must either be:
    # - knight
    # - for a territory within the kingdom that has no current title holder
    if self.feudal?
      if giver.king?
        if self.knight?
          return true
        end
        d = self.domain
        return true unless d.nil? or d.ruler  
      end
      return giver.has_title?(self.category, self.sub_category, self.territory) unless receiver.clergy?
    end
    # if title is ecclesiastical
    # - giver must be clergy
    # - the giver must have a title greater than the one being awarded
    if self.ecclesiastical?
      return false unless giver.clergy?
      highest = giver.highest_title
      return highest.sub_category > self.sub_category
    end
    # if title is court
    # - giver must be a ruler
    # - receiver must be a vassal of the giver
    # - receiver must not be a ruler
    if self.court?
      return false unless giver.ruler?
      return receiver.vassal?(giver) unless receiver.ruler?
      return true
    end
    raise "Unknown title category"
  end
  
  def revokeable?
    (self.category == 1 && self.sub_category > 2) || self.category == 3
  end
  
  def revoke
    return false unless self.revokeable?
    id = self.id
    ch = self.character
    c = self.category
    sc = self.sub_category
    t = self.domain
    liege = self.character.liege
    self.destroy
    # grant lord title if no titles remain
    if (ch.titles.nil? or ch.titles.size < 1)
      Title.grant_title(ch, 1, 1)
    end
    # revoking a feudal title of earl or greater gives the title back to the character's liege if he has one
    if c == 1 && sc > 2 && liege
      Title.grant_title(liege, c, sc, t)
    end
    # previous vassals of this title become vassals of lieges
    vassals = Relation.find_all_by_title_id_and_category (id, 1)
    if vassals
      vassals.each do |rel|
        if liege
          Title.revoke_court_titles rel.character # remove any court titles before changing allegiance
          rel.title_id = liege.highest_title.id
        else
          rel.title_id = ch.highest_title.id
        end
        rel.save
      end
    end
    # remove any vassals remaining if the character no longer holds a court
    Relation.free_vassals(ch) unless ch.ruler?
    return true
  end
  
  def name
    Title.name_of(self.category, sub_category, self.character.sex, self.domain)
  end
  
  def greater_rank_than? (title)
    return true unless title
    # priests and lords are the lowest rank possible
    if self.sub_category == 1 && !(self.category == 3)
      return false
    elsif title.sub_category == 1 && !(title.category == 3)
      return true
    end 
    # knights are worse than any court title
    if title.category == 3 && self.category == 1 && self.sub_category == 2
      return false
    elsif self.category == 3 && title.category == 1 && title.sub_category == 2
      return true
    end
    # earls and greater are better than any court title
    if title.category == 3 && self.category == 1 && self.sub_category > 2
      return true
    elsif self.category == 3 && title.category == 1 && title.sub_category > 2
      return false
    end
    # deans and greater are better than any court title
    if title.category == 3 && self.category == 2 && self.sub_category > 1
      return true
    elsif self.category == 3 && title.category == 2 && title.sub_category > 1
      return false
    end
    # all comparisons involving court titles should be done
    # cant compare ecclesiastical and feudal titles (shouldn't have both in same character) so raise an error
    raise "Characters may not possess both a feudal and ecclesiastical title at the same time!" unless self.category == title.category
    return self.sub_category > title.sub_category
  end
  
  def category_name
    Title.categories[self.category]
  end
  
  def sub_category_name
    Title.sub_categories(self.category)[self.sub_category][self.character.sex]
  end
  
   def salutation
    Title.salutations(self.category)[self.sub_category][self.character.sex]
    
  end
  
  def domain
    domain_type = Title.territory_type self.category, self.sub_category
    ret = nil
    if domain_type == "Kingdom"
      ret =  Kingdom.find(self.territory)
    end
    if domain_type == "Duchy"
      ret =  Duchy.find(self.territory)
    end
    if domain_type == "County"
      ret =  County.find(self.territory)
    end
    if domain_type == "Town"
      ret =  Town.find(self.territory)
    end
    # puts "domain_type=#{domain_type}, territory=#{self.territory}, domain=#{ret}"
    return ret
  end
  
  def feudal?
    self.category == 1
  end
  
  def ecclesiastical?
    self.category == 2
  end
  
  def court?
    self.category == 3
  end
  
  def knight?
    self.category == 1 && self.sub_category == 2
  end
  
  def lord?
    self.category == 1 && self.sub_category == 1
  end
  
  def priest?
    self.category == 2 && self.sub_category == 1
  end
  
  def pope?
    self.category == 2 && self.sub_category == 5
  end
  
  def emperor?
    self.category == 1 && self.sub_category == 7
  end
  
  def prestige
    Title.sub_categories(self.category)[self.sub_category]["prestige"]
  end
  
  def piety
    Title.sub_categories(self.category)[self.sub_category]["piety"]
  end
  
  protected
  def Title.sql_select_from_titles
    "SELECT DISTINCT t.id, t.character_id, t.category, t.sub_category, t.territory, t.created_at, t.updated_at FROM titles t "
  end
  
  def Title.find_by_court(sub_category, court)
    return nil unless sub_category && court
    ruler = court.ruler
    return nil unless ruler
    sql_ruler_titles = "SELECT title_id FROM titles WHERE character_id = #{ruler.id}"
    sql_vassals = "SELECT character_id FROM relations WHERE title_id IN (#{sql_ruler_titles})"
    sql = Title.sql_select_from_titles + " WHERE t.sub_category = #{sub_category} AND t.character_id IN (#{sql_vassals})"
    return Title.find_by_sql(sql)
  end
  
  def Title.title_holder (category, sub_category, territory = nil)
    territory_id = territory.nil? ? 0 : territory.id
    title = Title.find_by_category_and_sub_category_and_territory(category, sub_category, territory_id)
    return title.character unless title.nil?
  end
  
  
end
